﻿using HtmlAgilityPack;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Text;
using System.Web;
using System.Xml;
using System.Xml.Serialization;
using CrawlerCore.XmlData;
using CrawlerCore.MinPrice;
using CrawlerCore.Helper;
namespace CrawlerCore
{
    public class VietnamAirlines
    {
        private CrawlerHelper crawlerHelper { get; set; }
        private const string ONE_WAY = "OW";
        private const string ROUND_TRIP = "RT";
        private string address = "https://wl-prod.sabresonicweb.com/SSW2010/B3QE/webqtrip.html";
        public VietnamAirlines()
        {
            crawlerHelper = new CrawlerHelper();
        }
        private string getGetData(SearchInputService myInput)
        {
            StringBuilder getData = new StringBuilder("?");
            getData.Append("searchType=NORMAL");
            getData.Append("&lang=vt");
            string type = ONE_WAY;
            if (myInput.IsRoundTrip)
            {
                type = ROUND_TRIP;
                getData.Append("&returnDate=" + myInput.ReturnTime.ToString("yyyy-MM-dd"));
            }
            getData.Append("&journeySpan=" + type);
            getData.Append("&origin=" + myInput.DepartureCode);
            getData.Append("&destination=" + myInput.ArrivalCode);
            getData.Append("&numAdults=" + myInput.Adults);
            getData.Append("&numChildren=" + myInput.Children);
            getData.Append("&numInfants=" + myInput.Inf);
            getData.Append("&promoCode=");
            getData.Append("&radio_choice=on");
            getData.Append("&txtRecordLocator=");
            getData.Append("&txtETicketNumber=");
            getData.Append("&txtFFNumber=");
            getData.Append("&alternativeLandingPage=true");
            getData.Append("&departureDate=" + myInput.DepartTime.ToString("yyyy-MM-dd"));
            return getData.ToString();
        }
        public Root CreateXmlDocument(SearchInputService input)
        {
            Dictionary<int, string> listClassTicket;
            HtmlDocument d = crawlerHelper.getDocument(address, "GET", getGetData(input), null);
            Root rootxml = new Root();
            rootxml.Departure = input.DepartureCode;
            rootxml.Arrival = input.ArrivalCode;
            rootxml.outBound = new OutInBound();
            rootxml.inBound = new OutInBound();
            rootxml.AirLine = AirLineName.vietnamAirlines;
            if (input.IsRoundTrip)
            {
                HtmlNode nodeTh = d.DocumentNode.SelectNodes("//div[@id='dtcontainer-outbounds']/table/thead/tr").Single();
                listClassTicket = GetClass(nodeTh);
                HtmlNodeCollection collection = d.DocumentNode.SelectNodes("//div[@id='dtcontainer-outbounds']/table/tbody/tr");
                rootxml.outBound.Items = getListItems(input.DepartTime, collection, listClassTicket);

                //chieu ve
                nodeTh = d.DocumentNode.SelectNodes("//div[@id='dtcontainer-inbounds']/table/thead/tr").Single();
                listClassTicket = GetClass(nodeTh);
                collection = d.DocumentNode.SelectNodes("//div[@id='dtcontainer-inbounds']/table/tbody/tr");
                rootxml.inBound.Items = getListItems(input.ReturnTime, collection, listClassTicket);
            }
            else
            {
                HtmlNode nodeTh = d.DocumentNode.SelectNodes("//div[@id='dtcontainer-both']/table/thead/tr").Single();
                listClassTicket = GetClass(nodeTh);
                HtmlNodeCollection collection = d.DocumentNode.SelectNodes("//div[@id='dtcontainer-both']/table/tbody/tr");
                rootxml.outBound.Items = getListItems(input.DepartTime, collection, listClassTicket);
            }
            //XmlSerializer serializer = new XmlSerializer(typeof(Root));
            //TextWriter writer = new StreamWriter(folderPath + "VietnamAirlines_" + input.SessionId + ".xml");
            //serializer.Serialize(writer, rootxml);
            //writer.Close();
            return rootxml;
        }
        private Dictionary<int, string> GetClass(HtmlNode nodeTh)
        {
            Dictionary<int, string> dic = new Dictionary<int, string>();
            for (int i = 6; i < 13; i++)
            {
                try
                {
                    string name = nodeTh.SelectSingleNode("th[" + i + "]/span/span").InnerText;
                    dic.Add(i, name);
                }
                catch { }
            }

            return dic;
        }
        private List<Item> getListItems(DateTime date, HtmlNodeCollection collection, Dictionary<int, string> listClassTicket)
        {
            try
            {
                List<Item> items = new List<Item>();
                foreach (HtmlNode node in collection)
                {
                    try
                    {
                        Item item = new Item();
                        HtmlNode node2 = node.SelectSingleNode("td[1]/p/a");
                        item.flightNo = node2.InnerText;
                        node2 = node.SelectSingleNode("td[3]/span");
                        item.departureTime = DateTimeHelper.getDate(date, node2.InnerText);
                        node2 = node.SelectSingleNode("td[4]/span");
                        item.arriveTime = DateTimeHelper.getDate(date, node2.InnerText);
                        //prices
                        List<Price> prices = new List<Price>();
                        Price p;

                        for (int i = 6; i < 13; i++)
                        {
                            try
                            {
                                node2 = node.SelectSingleNode("td[" + i + "]//span[@class='prices-alternative']");
                                p = new Price();
                                p.name = listClassTicket[i];
                                p.price = node2.InnerText.Replace("&nbsp;", " ").Replace(" VND", "").Replace(",", "");
                                prices.Add(p);
                            }
                            catch { }
                        }
                        item.price = prices;
                        items.Add(item);
                    }
                    catch { }
                }
                return items;
            }
            catch
            {
                return null;
            }
        }
        public RootMinPrice GetPriceInFare(SearchInputService input)
        {
            try
            {
                CrawlerHelper helper = new CrawlerHelper();
                HtmlDocument htmld = crawlerHelper.getDocument(address, "GET", getGetData(input), null);
                RootMinPrice root = new RootMinPrice();
                if (input.IsRoundTrip)
                {
                    HtmlNode nodeTemp = htmld.DocumentNode.SelectSingleNode("//div[@id='outbounds-menu-dates-instance-container']/div/div/div/ul");
                    root.departurePrices = new OutInBoundPrices();
                    root.departurePrices.prices = GetListPrices(nodeTemp);
                    root.arrivePrices = new OutInBoundPrices();
                    nodeTemp = htmld.DocumentNode.SelectSingleNode("//div[@id='inbounds-menu-dates-instance-container']/div/div/div/ul");
                    root.arrivePrices.prices = GetListPrices(nodeTemp);
                }
                else
                {
                    HtmlNode nodeTemp = htmld.DocumentNode.SelectSingleNode("//div[@id='both-menu-dates-instance-container']/div/div/div/ul");
                    root.departurePrices = new OutInBoundPrices();
                    root.departurePrices.prices = GetListPrices(nodeTemp);
                }
                return root;
            }
            catch
            {
                return null;
            }
        }

        private List<MinPriceDetail> GetListPrices(HtmlNode nodeTemp)
        {
            if (nodeTemp == null)
            {
                return null;
            }
            try
            {
                List<MinPriceDetail> l = new List<MinPriceDetail>();
                HtmlNodeCollection collectionLi = nodeTemp.SelectNodes("li");
                foreach (HtmlNode node in collectionLi)
                {
                    try
                    {
                        MinPriceDetail m = new MinPriceDetail();
                        m.Date = DateTime.Parse(node.SelectSingleNode("a/span[1]").Attributes["data-wl-date"].Value.Split(',')[0]);
                        m.Price = node.SelectSingleNode("a/span[2]/span/span/span[1]").InnerText.Replace(",", "");
                        l.Add(m);
                    }
                    catch
                    {

                    }
                }
                return l;
            }
            catch
            {
                return null;
            }
        }

    }
}